<script lang="tsx">
const items2CatalogItemsMap = (items: CourseItem[]) => {
  const map = new Map<CourseCatalog["id"], CourseItem[]>();
  items.forEach((item) => {
    const list = map.get(item.catalogId);
    if (list) {
      list.push(item);
    } else {
      map.set(item.catalogId, [item]);
    }
  });
  return map;
};
</script>

<script lang="tsx" setup>
import { TreeNode, buildTreeByParentId } from "@/utils/tree";
import Catalog from "./components/catalog.vue";
import {
  CourseItem,
  CourseCatalog,
  Course,
  CourseItemDetail,
  CourseItemType,
  PlayingInfo,
  CourseVideo,
  CourseLive,
  CourseQuestionSet,
} from "@/types/course";
import * as CourseApi from "@/api/train/course";
import { useRouter } from "vue-router";
import PageHeader from "./components/page-header.vue";
import PageBanner from "./components/page-banner.vue";
import PageDetails from "./components/page-details.vue";
import PageFooter from "./components/page-footer.vue";
import { useIntersectionObserver } from "@vueuse/core";
import * as OrderApi from "@/api/train/order";
import { showNotify, showToast } from "@nutui/nutui";
import { useCourseStore } from "@/store/modules/course";
import { listItem } from "@/api/train/course";
import { CarType, Subject } from "@/types/practice";
import { HistoryRound, AssessmentOutlined, MenuBookRound, BookmarkBorderRound } from "@vicons/material";
import { Icon } from "@vicons/utils";
import { isIOS, isMiniProgram } from "@/utils/mini-program";
import { showDialog } from "@nutui/nutui";
import "@nutui/nutui/dist/packages/dialog/style";
const router = useRouter();
const courseStore = useCourseStore();

const props = defineProps<{ id: string }>();
const { id: courseId } = props;

/** 课程信息 */
const course = ref<Course | null>(null);

/** 目录树 */
const catalogTree = ref<TreeNode<CourseCatalog, CourseCatalog["id"]>[]>([]);
const updateCatalogTree = (catalogList: CourseCatalog[]) =>
  (catalogTree.value = buildTreeByParentId<CourseCatalog, CourseCatalog["id"]>(catalogList));

/** 目录下的项目 */
const itemsMap = ref<Map<CourseItem["id"], CourseItem>>(new Map());
const catalogItemsMap = ref<Map<CourseCatalog["id"], CourseItem[]>>(new Map());
const updateCatalogItemsMap = (itemList: CourseItem[]) => {
  itemsMap.value = new Map(itemList.map((item) => [item.id, item]));
  catalogItemsMap.value = items2CatalogItemsMap(itemList);
  skipNextItem();
};

/** 项目的明细 */
const itemDetailMap = ref<Map<CourseItem["courseItemTypeId"], CourseItemDetail>>(new Map());
const handleAddItemDetail = (itemDetail: CourseItemDetail) => {
  if (!itemDetail) return;
  itemDetailMap.value.set(itemDetail.id, itemDetail);
  itemDetailMap.value = new Map(itemDetailMap.value);
};

/** 是否有题目 */
const hasQuestion = computed(() => [...itemsMap.value.values()].some((item) => item.courseItemType === CourseItemType.QUESTION));

/** 初始化信息 */
const initData = () => {
  console.log("initData");
  const coursePromise = CourseApi.getCourseById(courseId).then((res) => {
    course.value = res.data;
    courseStore.updateVIP(res.data.price !== 0);
  });
  const catalogPromise = CourseApi.getCourseCatalogListByCourseId(courseId).then((res) => updateCatalogTree(res.data));
  const itemPromise = CourseApi.getCourseItemListByCourseId(courseId).then((res) => updateCatalogItemsMap(res.data));
  return Promise.all([coursePromise, catalogPromise, itemPromise]);
};

initData().then(() =>
  Object.entries(courseStore.catalogHistory[courseId])
    .filter(([key, catalogId]) => key !== "item" && catalogId)
    .forEach(([_, catalogId]) => {
      listItem(catalogId).then((res) => res.data.map(handleAddItemDetail));
    })
);

// 标题栏相关
const detailEle = ref<{ rootElement: HTMLDivElement | null }>();
/** 详情组件是否可见 */
const detailVisible = ref(false);
onMounted(() => {
  useIntersectionObserver(detailEle.value!.rootElement, ([{ isIntersecting }]) => (detailVisible.value = !!window.scrollY && isIntersecting));
});
/** 滚动到详情页 */
const scrollToDetail = () =>
  detailEle.value?.rootElement?.scrollIntoView({
    behavior: "smooth",
  });

// 购买弹窗相关
const buyDialogVisible = ref(false);
const isFree = computed(() => !course.value?.price);
/** 购买事件 */
const handleBuy = async () => {
  router.push({
    path: `/buy/${course.value?.skuId}`,
  });
};

// 当前播放视频
const playingInfo = ref<PlayingInfo | null>(null);
// provide("updatePlayingInfo", (info: PlayingInfo | null) => {
//   playingInfo.value = info;
// });

// 提供给子组件的方法
provide("handleBuy", async () => {
  if (isIOS() && isMiniProgram() && !isFree.value) {
    showDialog({
      title: "提示",
      content: "请咨询相关驾校",
      noCancelBtn: true,
      onCancel: () => {},
      onOk: () => {},
    });
  } else {
    if (isFree.value) {
      if (!course.value || course.value?.purchased) return;
      const res = await OrderApi.createOrder({
        skuId: course.value.skuId,
        amount: 1,
        orderPrice: 0,
        remark: "",
      });
      const orderId = res.data;
      const orderRes = await OrderApi.getOrderById(orderId);
      if (orderRes.data) {
        showNotify.primary("报名成功");
        // await initData();
        window.location.reload();
      }
    } else {
      buyDialogVisible.value = true;
    }
  }
});

// item选中事件
const handleItemSelect = (item: CourseItem) => {
  if (!item) return;
  courseStore.updateCurrentChapter({ itemId: item.id, catalogId: item.catalogId });
  if (item.courseItemType === CourseItemType.VIDEO) {
    // 延迟获取数据
    setTimeout(() => {
      const videoDetail = itemDetailMap.value.get(item.courseItemTypeId) as CourseVideo | undefined;
      if (!videoDetail) {
        playingInfo.value = null;
        showToast.text("无法获取视频信息");
        return;
      }

      console.log("videoDetail: ", videoDetail);
      playingInfo.value = {
        vid: videoDetail.bjyVideoId,
        seek: 0,
        videoId: videoDetail.id,
      };
    }, 700);
  } else if (item.courseItemType === CourseItemType.ARTICLE) {
    router.push({
      path: `/course/article/${item.courseItemTypeId}`,
    });
  } else if (item.courseItemType === CourseItemType.QUESTION) {
    // 跳转到题目页面
    const set = itemDetailMap.value.get(item.courseItemTypeId) as CourseQuestionSet | undefined;
    console.log("set: ", set);
    router.push({
      path: "/practice/set",
      query: {
        id: item.courseItemTypeId,
        courseId,
        itemId: item.id,
        carType: set?.carType || CarType.A1,
        subject: set?.subject || Subject.ONE,
      },
    });
  } else if (item.courseItemType === CourseItemType.LIVE) {
    const live: CourseLive | undefined = itemDetailMap.value.get(item.courseItemTypeId) as CourseLive | undefined;

    if (!live) return showToast.text("无法获取直播间信息");

    // 获取直播间状态
    CourseApi.getCourseLive(live.id).then(({ data: { liveStatus, liveUrl } }) => {
      console.log("liveStatus", liveStatus, liveUrl);
      if (liveStatus === -1) return showToast.text("当前直播间未开播");
      if (liveStatus === 0) return showToast.text("当前直播间未开播");
      courseStore.setLiveUrl(liveUrl);
      router.push({ path: "/course/live" });
    });
  } else if (item.courseItemType === CourseItemType.EXAM) {
    console.log("item", item.courseItemTypeId.toString().split(""));
    const [carType, subject] = item.courseItemTypeId.toString().split("");
    router.push({
      path: `/practice/practice`,
      query: {
        carType,
        subject,
        courseId,
      },
    });
  }
};

// 当前选中item
const currentItemId = computed({
  // 从历史记录中获取
  get: () => courseStore.catalogHistory[courseId]?.item || "",
  set: (val) => {
    courseStore.updateCatalogHistory(courseId, "item", val);
  },
});
provide("updateCurrentItem", (item: CourseItem) => {
  currentItemId.value = item.id;
  courseStore.updateCatalogHistory(courseId, "item", item.id);

  handleItemSelect(item);
});

const updateCurrentItem = (item: CourseItem) => {
  currentItemId.value = item.id;
  courseStore.updateCatalogHistory(courseId, "item", item.id);

  handleItemSelect(item);
};
// 自动跳转道下一章
const skipNextItem = async () => {
  if (!courseStore.isSkip) return;
  // 选择出在那个章节下的内容
  const { catalogId, itemId } = courseStore.currentChapter;
  // 获取该章节下的列表
  let listChapter: any = [];
  catalogItemsMap.value.forEach((values, keys) => {
    if (keys === catalogId) {
      listChapter = values;
    }
  });
  // 判断该章节存在那个位置
  const index = listChapter.findIndex((item: any) => {
    return item.id === itemId;
  });
  // 判断下面是否还有章节
  if (index >= listChapter.length - 1) {
    courseStore.updateSkip(false);
    // 该章已是最后一章
    showDialog({
      title: "温馨提示",
      content: "该章节已是最后一个章节",
      noCancelBtn: true,
      onOk: () => {},
    });
  } else {
    courseStore.updateSkip(false);
    // 自动跳转下一章
    updateCurrentItem(listChapter[index + 1]);
  }
};
</script>

<template>
  <div class="bg-gray-1 min-h-screen">
    <page-header :detail-visible="detailVisible" @scroll-to-detail="scrollToDetail" />

    <page-banner
      :cover-url="course?.courseCoverUrl"
      :course-id="courseId"
      :playing-info="playingInfo"
      :current-item-id="currentItemId"
      :items-map="itemsMap"
      :item-detail-map="itemDetailMap"
    />
    <div class="bg-white">
      <nut-grid column-num="4" :border="false" :style="{ '--nut-grid-item-content-bg-color': 'transparent' }">
        <!-- 题目相关 -->
        <template v-if="hasQuestion">
          <nut-grid-item text="错题练习" :to="`/practice/history/wrong?courseId=${props.id}`">
            <Icon size="30" color="#1667c3">
              <AssessmentOutlined />
            </Icon>
          </nut-grid-item>
          <nut-grid-item text="题目收藏" :to="`/practice/history/favorite?courseId=${props.id}`">
            <Icon size="30" color="#1667c3">
              <BookmarkBorderRound />
            </Icon>
          </nut-grid-item>
        </template>

        <!-- 模考相关 -->
        <template v-if="course?.ifContainMockExam">
          <!-- <nut-grid-item
            text="开始模考"
            :to="`/practice/practice?courseId=${courseId}&carType=${course?.carType || CarType.A1}&subject=${course?.subject || Subject.ONE}`"
          >
            <Icon size="30" color="#1667c3">
              <HistoryRound />
            </Icon>
          </nut-grid-item> -->
          <nut-grid-item
            text="模考历史"
            :to="`/practice/exam-history?carType=${course?.carType || CarType.A1}&subject=${course?.subject || Subject.ONE}`"
          >
            <Icon size="30" color="#1667c3">
              <HistoryRound />
            </Icon>
          </nut-grid-item>
          <nut-grid-item
            text="模考攻略"
            :to="`/practice/exam-strategy?carType=${course?.carType || CarType.A1}&subject=${course?.subject || Subject.ONE}`"
          >
            <Icon size="30" color="#1667c3">
              <MenuBookRound />
            </Icon>
          </nut-grid-item>
        </template>
      </nut-grid>
    </div>

    <div class="bg-white pb-3">
      <h2 class="mt-3 p-3 c-slate-7 text-xl">课程目录</h2>
      <catalog
        v-if="course"
        :course-id="course.id"
        :current-item-id="currentItemId"
        :purchased="course.purchased"
        :catalog-tree="catalogTree"
        :catalog-items-map="catalogItemsMap"
        :item-detail-map="itemDetailMap"
        @add-item-detail="handleAddItemDetail"
      />
    </div>

    <page-details ref="detailEle" :course-detail="course?.courseDetail" />

    <page-footer :is-free="isFree" :purchased="course?.purchased" />

    <!-- 购买弹窗 -->
    <nut-dialog
      teleport="#app"
      title="提示"
      content="购买后即可解锁完整课程"
      ok-text="立即购买"
      cancel-text="我再想想"
      @ok="handleBuy"
      @cancel="buyDialogVisible = false"
      v-model:visible="buyDialogVisible"
    />
  </div>
</template>
